
// config 只可以监听1级往后的对象  只可以清空1级往后的属性  只可以删除2级往后的属性
//需要js-md5的支持 用来判断子数据是否更新
//需要自己封装的request______

function up_ws_class1(obj_params) {  
    let _this=this;
    _this.connect_flag=false;
    _this.log_flag=false;
    _this.log_print=function(...args){
        // console.log(...args)
        if(_this.log_flag==true){
            // console.log(...args)
        }
    }
    
    _this.template_name="lhp_set_config_____1";
    //待更新的列表
    _this.objs=[];
    //数据
    _this.data={};
    //匹配路径
    _this.check_path=function(a, b) {  
        //a:监听的路径
        //b:修改的路径
        // 检查字符串a是否是字符串b的前缀  
        // console.log("ba",b,a)
        if (a==b){
            return {type:true,path:''}
        }
        else if(a==''){
            return {type:true,path:b}; 
        }
        else if (b.startsWith(a)) {  
            // aa.bb   aa.bb.cc  {type:true,path:'cc'}
            // aa.bbb  aa.bb.cc  {type:false}
            _this.log_print('"',a,'" "',b,'"')
            let new_path=b.slice(a.length)
            if(new_path[0]!='.'){
                return {type:false}
            }else{
                return {type:true,path:new_path.slice(1)}; 
            }
            
        }  
        // 检查字符串b是否是字符串a的前缀 
        // aa.aa.bb    aa.a   {type:false}    
        // aa.aa.bb    aa.aa  {type:true,path:''}
        else if (a.startsWith(b)) {  
            if(a.slice(b.length)[0]=='.'||b==''){
            return {type:true,path:''};  
            }else{
                return {type:false}
            }
        }  
        // 如果都不是前缀，则根据需求返回相应的值（这里假设返回b）  
        else {  
            return {type:false}; 
        }  
    }  
    
    _this.check_path2=function(a, b) {  
        //a:监听的路径
        //b:修改的路径
        // 检查字符串a是否是字符串b的前缀  
        if (b.startsWith(a)&&(a!=b)) {
            // aa.bb   aa.bb.cc  {type:true,path:'cc'}
            // aa.bbb  aa.bb.cc  {type:false}
            let new_path=b.slice(a.length)
            if(new_path[0]!='.'){
                return false
            }else{
                return true; 
            }
            
        }
        // 如果都不是前缀，则根据需求返回相应的值（这里假设返回b）  
        else {
            return false; // 或者可以返回a，或者抛出错误，取决于你的需求  
        }  
    }  
    //同步数据到注册中
    _this.update_val2regist=function(obj){
        if(obj.data_type=="set_list"&&obj.path){
            for(let i=0;i<_this.objs.length;i++){
                let oobj=_this.objs[i];
                let check_res=_this.check_path(oobj.path,obj.path);
                // _this.log_print(occheck_path,ccheck_path,"匹配路径:",check_res)
                if (check_res.type==false){continue}
                console.log(oobj._this.data.var_name,'匹配路径成功',oobj.path,obj.path,'【',check_res.path,'】')
                oobj.func(obj)
            }
            // return
        }
        //obj 被同步的数据
        //##################开始匹配路径然后同步数据
if(!Array.isArray(obj.path)){obj.path=[obj.path]}
for (let kkkk=0;kkkk<obj.path.length;kkkk++){
    let ccheck_path=obj.path[kkkk];
    for(let i=0;i<_this.objs.length;i++){
        let oobj=_this.objs[i];
        _this.log_print(oobj._this.data.var_name,"更新第",i+1,"个注册对象:",oobj);
        //匹配路径 不满足就跳过当前匹配 不更新注册对象 【不运行注册对象的回调函数】
        _this.log_print(oobj._this.data.var_name,'当前匹配',i+1,'//',_this.objs.length,oobj,'//',_this.objs)
        try{if(oobj._this.data.test_flag==true){_this.log_print(oobj._this.data.var_name,'开始匹配路径:',oobj.path,ccheck_path)};}catch{}
        
        let check_res=_this.check_path(oobj.path,ccheck_path);
        // _this.log_print(occheck_path,ccheck_path,"匹配路径:",check_res)
        if (check_res.type==false){
            _this.log_print(oobj._this.data.var_name,'匹配路径不成功',oobj.path,ccheck_path,'【',check_res.path,'】');
            continue}
            _this.log_print(oobj._this.data.var_name,'匹配路径成功',oobj.path,ccheck_path,'【',check_res.path,'】');
        let now_check_path=oobj.path;
        if (oobj.path==''){now_check_path=check_res.path}
        else if (check_res.path!=''){now_check_path=now_check_path+'.'+check_res.path}
        
        
        try{if(oobj._this.data.test_flag==true){_this.log_print(oobj._this.data.var_name,'匹配路径成功:',now_check_path)};}catch{}
            // try{
                //新增数据  或者 修改数据
                if (obj.data_type=="postput"){
                
                _this.log_print("开始更新postput:",obj);
                let temp_val1=_this.data;
                try{if(oobj._this.data.test_flag==true){_this.log_print(oobj._this.data.var_name,'开始计算数据:postput')}}catch{}
                let temp_val2=[];
                //根据注册信息 找到路径上的数据
                if(now_check_path!=''){temp_val2=now_check_path.split(".");}
                _this.log_print('now_check_path',temp_val1,now_check_path)
                for(let j=0;j<temp_val2.length;j++){temp_val1=temp_val1[temp_val2[j]]}
                //匹配md5值
                // let new_md5=md5(JSON.stringify(temp_val1));
                // if (new_md5!=oobj.md5[now_check_path]){
                //     oobj.md5[now_check_path]=new_md5;
                //     let paramss={path:check_res.path,data:temp_val1,data_type:obj.data_type};
                //     // _this.log_print("组件:",oobj,oobj._this.data.var_name,"更新数据:",paramss);
                //     //执行回调
                //     oobj.func(paramss);
                // }
                let paramss={path:check_res.path,data:temp_val1,data_type:obj.data_type};
                try{if(oobj._this.data.test_flag==true){_this.log_print(oobj._this.data.var_name,"传参数据1:",paramss)}}catch{}
                oobj.func(paramss);
            }

                //删除数据 或者 清空数据
                else if (obj.data_type=="delete"){
                // _this.log_print("更新delete:",obj);
                //删除相关的临时变量【用于存储md5
                //删除子集
                // for (let key in oobj.md5){
                //     if(this.check_path2(now_check_path,key)){delete oobj.md5[key]}
                // }
                // //删除当前
                // delete oobj.md5[now_check_path]
                //执行回调
                let callback_params={path:check_res.path,data_type:obj.data_type};
                // _this.log_print("执行回调:",callback_params);
                oobj.func(callback_params)}
                else if(obj.data_type=="clear"){
                // _this.log_print("更新clear:",obj);
                //删除相关的临时变量【用于存储md5
                //删除子集
                // for (let key in oobj.md5){
                //     if(this.check_path2(now_check_path,key)){try{delete oobj.md5[key]}catch{}}
                // }
                // oobj.md5[now_check_path]=clear_md5;//设置md5
                //执行回调
                let callback_params={path:check_res.path,data_type:obj.data_type};
                // _this.log_print("执行回调:",callback_params);
                oobj.func(callback_params)}
                else if (obj.data_type=="insert"){
                
                    // _this.log_print("更新postput:",obj);
                    let temp_val1=_this.data;
                    try{if(oobj._this.data.test_flag==true){_this.log_print(oobj._this.data.var_name,'开始计算数据:postput')}}catch{}
                    let temp_val2=[];
                    //根据注册信息 找到路径上的数据
                    if(now_check_path!=''){temp_val2=now_check_path.split(".");}
                    for(let j=0;j<temp_val2.length;j++){temp_val1=temp_val1[temp_val2[j]]}
                    //匹配md5值
                    // let new_md5=md5(JSON.stringify(temp_val1));
                    // if (new_md5!=oobj.md5[now_check_path]){
                    //     oobj.md5[now_check_path]=new_md5;
                    //     let paramss={path:check_res.path,data:temp_val1,data_type:obj.data_type};
                    //     // _this.log_print("组件:",oobj,oobj._this.data.var_name,"更新数据:",paramss);
                    //     //执行回调
                    //     oobj.func(paramss);
                    // }
                    let paramss={path:check_res.path,data:temp_val1,data_type:obj.data_type,before_idx:obj.before_idx};
                    try{if(oobj._this.data.test_flag==true){_this.log_print(oobj._this.data.var_name,"传参数据1:",paramss)}}catch{}
                    oobj.func(paramss);
                }
            // }
            // catch{
                if(oobj.error_count==undefined){oobj.error_count=1;}
                else{oobj.error_count++;}
                if (oobj.type=='try1'&&oobj.error_count>1){_this.objs.slice(i,1);i--;}
                else if (oobj.type=='try2'){_this.objs.slice(i,1);i--;}
            // }
        
    }
}
    },
    //同步数据到其他组件
    _this.update_val=function(obj){
        let new_obj=JSON.parse(JSON.stringify(obj))
        // _this.log_print("接收的数据:",obj)
        // _this.log_print("当前注册信息数量:",_this.objs.length)
        // _this.log_print("当前注册信息:",_this.objs)
        let clear_md5=null;
        // _this.log_print("匹配other_callback",1);
        //匹配其他回调
        let temp_key=null;let temp_val=null;

        //初始化数据
        if (obj.type=="change_data"){
            
            //##################将数据保存到当前对象中
            //路径为'' 表示 获取的是完整的配置 
            if(obj.path==''){
                _this.data=obj.data;
                _this.get_all_flag=true;//获取所有配置完成
            //postput表示新增数据或者修改数据   直接通过函数拷贝就行
            }else if(obj.data_type=="postput"){
                let res=lhp_set_config_websocket_set_data.postput({
                    data:_this.data,
                    path:obj.path,
                    copy_data:obj.data
                })
                if(res.type=="error"){
                    _this.log_print(res.message);
                    return
                }
                
    _this.log_print("开始同步数据到注册的组件中...")
    _this.update_val2regist(obj);//同步数据到注册中
            }
            //删除数据  只有_this.data.xxx.xxx 更子一级的才可以被删除  第一层子级 不允许被删除
            else if(obj.data_type=="delete"){
                let res=null;
                if (typeof obj.path==='string'){
                    res=lhp_set_config_websocket_set_data.delete({
                    data:_this.data,
                    path:obj.path,
                    })
                    if(res.type=="error"){
                        _this.log_print(res.message);
                        return
                    }

                }else if( Array.isArray(obj.path)){
                    for (let zzzz=0;zzzz<obj.path.length;zzzz++){
                        res=lhp_set_config_websocket_set_data.delete({
                        data:_this.data,
                        path:obj.path[zzzz],
                        })
                        if(res.type=="error"){
                            _this.log_print(res.message);
                            return
                        }

                    }
                }
    
            
    _this.update_val2regist(obj);//同步数据到注册中
    //类型为清空数据
    }else if(obj.data_type=="clear"){
        
        let res=lhp_set_config_websocket_set_data.clear({
            md5_flag:true,
            data:_this.data,
            path:obj.path,
        })
    if(res.type=="error"){
        _this.log_print(res.message);
        return
    }
    clear_md5=res.md5
    
    _this.update_val2regist(obj);//同步数据到注册中
}else if(obj.data_type=='set_list'){
        if(!(obj.delete===undefined)){
            for (let idx_=0;idx_<obj.delete.length;idx_++){
                if (typeof obj.delete[idx_].path==='string'){
                    let res=lhp_set_config_websocket_set_data.delete({
                    data:_this.data,
                    path:obj.delete[idx_].path,
                    })
                }else if( Array.isArray(obj.delete[idx_].path)){
                    for (let zzzz=0;zzzz<obj.delete[idx_].path.length;zzzz++){
                        let res=lhp_set_config_websocket_set_data.delete({
                        data:_this.data,
                        path:obj.delete[idx_].path[zzzz],
                        })
    
                    }
                }
                obj.delete[idx_].data_type='delete';
                _this.update_val2regist(obj.delete[idx_]);//同步数据到注册中
    
            }
        }
        if(!(obj.delete2===undefined)){
            for (let idx__1=0;idx__1<obj.delete2.length;idx__1++){
    
                let objjj_lst=obj.delete2[idx__1].lst
                let ppah_before=obj.delete2[idx__1].delete_before
                for (let idx_=0;idx_<objjj_lst.length;idx_++){
                        let del_dct={
                            data:_this.data,
                            path:ppah_before+'.'+objjj_lst[idx_],
                            }
                        let res=lhp_set_config_websocket_set_data.delete(del_dct)
                        del_dct.data_type='delete';
                    _this.update_val2regist(del_dct);//同步数据到注册中
        
                }
    
            }
        }
        if(!(obj.clear===undefined)){
            for (let idx_=0;idx_<obj.clear.length;idx_++){
                let res=lhp_set_config_websocket_set_data.clear({
                    md5_flag:true,
                    data:_this.data,
                    path:obj.clear[idx_].path,
                })
                obj.clear[idx_].data_type='clear';
                _this.update_val2regist(obj.clear[idx_]);//同步数据到注册中
    
            }
        }
        if(!(obj.postput===undefined)){
            
            for (let idx_=0;idx_<obj.postput.length;idx_++){
                let res=lhp_set_config_websocket_set_data.postput({
                    md5_flag:true,
                    data:_this.data,
                    path:obj.postput[idx_].path,
                    copy_data:obj.postput[idx_].data
                })
                obj.postput[idx_].data_type='postput';
                _this.update_val2regist(obj.postput[idx_]);//同步数据到注册中
    
            }
        }
        if(!(obj.insert===undefined)){
    
            for (let idx_=0;idx_<obj.insert.length;idx_++){
                let res=lhp_set_config_websocket_set_data.insert({
                    md5_flag:true,
                    data:_this.data,
                    path:obj.insert[idx_].path,
                    copy_data:obj.insert[idx_].data,
                    before_idx:obj.insert[idx_].before_idx
                })
                obj.insert[idx_].data_type='insert';
                _this.update_val2regist(obj.insert[idx_]);//同步数据到注册中
    
            }
        }
    }
    

    if(obj.path){
        console.log("start run update_val2regist",new_obj)
        _this.update_val2regist(new_obj);//同步数据到注册中
    }

          
            
        }
        //匹配其他回调
        if (!(obj.other_callback===undefined)){
            // _this.log_print("匹配other_callback",2);
            for (let temp_idx=0;temp_idx<obj.other_callback.length;temp_idx++){
                // _this.log_print("匹配other_callback",3);
                temp_key=obj.other_callback[temp_idx].key;//回调的key
                temp_val=obj.other_callback[temp_idx].data;//回调的参数
                //遍历注册对象 匹配注册 然后更新
                for(let i=0;i<_this.objs.length;i++){
                    let oobj=_this.objs[i];
                    // _this.log_print("匹配other_callback",4,i,oobj,oobj.other_callback,temp_key);
                    if(!(oobj.other_callback===undefined)){
                        if (temp_key in oobj.other_callback){
                            try{
                                // _this.log_print("匹配other_callback",5,temp_key,temp_val);
                                oobj.other_callback[temp_key](temp_val);
                                // _this.log_print("匹配other_callback",6);
                            }catch (err){_this.log_print(oobj._this.data.var_name,"匹配other_callback 7",temp_key,'异常，执行函数时出错:',err)}
                        }
                    }
                }
            }
        }
    }
    //连接服务器的websocket
    _this.connect_socket=function(func){
        
        _this.log_print("1开始连接服务器")
    _this.ws = new WebSocket("ws://" + window.location.host + "/websocket");
    // WebSocket连接成功后的回调
    _this.ws.onopen = function(event) {
        _this.connect_flag=true;
        _this.log_print("2运行连接成功后执行的回调函数")
        try{func()}catch{}//func 运行连接成功后执行的回调函数
        //params 附带参数 如账号信息
        // _this.ws.send(JSON.stringify({params:{},"type":"get_all"}));
        // _this.ws.send(JSON.stringify({params:_this.return_params(),"type":"get_all"}));
    };
    // 接收服务器消息的回调
    _this.ws.onmessage = function(event) {
        // _this.log_print("3接收服务器消息的回调")
        //格式化数据
        // _this.log_print("1.格式化数据")
        let recv_data=null;
        try{recv_data=JSON.parse(event.data);}catch{
            Vue.prototype.$notify({type: 'error',message: 'event.data错误'});
            _this.log_print("event.data转json错误:",event.data);
            return
        }
        // _this.log_print("2.异常检查")
        //如果是错误信息 则弹窗
        if (recv_data.type=="error"){
            Vue.prototype.$notify({type: 'error',message: recv_data.message||'错误'});_this.log_print("数据更新失败:",recv_data.message,recv_data);return null;}
        // try{
            //将服务器下发的数据转为json格式 {path:"更新数据的路径 为空代表所有数据","data":data}
            
        let start_ti=new Date().getTime();
        console.log("开始更新");
        
        console.log("ws接收服务端等待时间:",(new Date().getTime()-window.上传服务器时间)/1000)
            _this.update_val(recv_data);
        console.log("更新耗时: " + (new Date().getTime()-start_ti)/1000 + " 秒");
        // }
        // catch{Vue.prototype.$notify({type: 'error',message: '函数运行错误'});}
    };

    // WebSocket关闭时的回调
    _this.ws.onclose = function(event) {
        _this.log_print("4websocket已经关闭.");
        _this.connect_socket();
    };
    // 错误处理
    _this.ws.onerror = function(error) {
        console.error("5WebSocket错误:", error);
    };
    }
    _this.add_params_func_lst=[];
    // 添加前置执行函数 func({"func":func,"path":path})
    // path为要监听的路径 通过判断path路径的md5值是否一致来更新 如果path路径不存在 则不执行
    _this.before_objs=[];
    _this.add_before_func=function(obj){
        _this.before_objs.push(obj);
    }

    _this.lhp_vue_set=function(obj_){
        let data_type=obj_.data_type;//要修改的数据类型  post||put delete clear
        let _this=obj_._this;//this vue对象
        let path=obj_.path;//path为data_obj要修改的数据的路径
        let data=obj_.data;//data为修改的数据
        //类型为新增或者修改
        if (data_type=='postput'){
        let change_obj=_this.data;
        let last_path=null;
        if (path.indexOf(".") !== -1){
            let path_lst=path.split(".");
            for (let i=0;i<path_lst.length-1;i++){change_obj=change_obj[path_lst[i]]}
            last_path=path_lst[path_lst.length-1];
        }else{last_path=path}
        // console.log("path",path)
        // console.log("_this.$set(change_obj,last_path,data)",change_obj,last_path,data)
        _this.$set(change_obj,last_path,JSON.parse(JSON.stringify(data)))
        //类型为删除
        }else if(data_type=="delete"){
            let change_obj=_this.data;
            let father_idx=null;
            let father_obj=null;
            if (path.indexOf(".") !== -1){
                let path_lst=path.split(".");
                if (path_lst.length<=1){console.log("delete异常 数量小于等于1");
return}
                for (let i=0;i<path_lst.length-1;i++){father_obj=change_obj;father_idx=path_lst[i];change_obj=change_obj[path_lst[i]];}
                let last_idx=path_lst[path_lst.length-1];
                let new_data=JSON.parse(JSON.stringify(change_obj));
                if(typeof new_data =="object") {  
                    if (Array.isArray(new_data)){
                        new_data.splice(last_idx,1);
    
                    }else{
                        delete new_data[last_idx]
                    }
                _this.$set(father_obj,father_idx,new_data)
            }}else{console.log("delete异常 数量小于2");
return}
    
            
    //类型为清空数据
    }else if(data_type=="clear"){
        let change_obj=_this.data;
        let last_key=null;
        if (path.indexOf(".") !== -1){
            let path_lst=path.split(".");
            for (let i=0;i<path_lst.length-1;i++){change_obj=change_obj[path_lst[i]]}
            last_key=path_lst[path_lst.length-1];
        }else{
            last_key=path;
        
        }
        let temp_val=change_obj[last_key]
    switch (typeof temp_val) {  
            case 'object':  
                // 注意：这里会匹配到null，因为null也是object类型  
                // 需要额外检查是否为null  
                if (temp_val === null) {  
                    change_obj[last_key] = null; // 或者你可以将null也设置为{}  
                } else if (Array.isArray(temp_val)) {  
                    change_obj[last_key] = [];  
                } else {  
                    change_obj[last_key] = {};  
                }  
                break;  
            case 'string':  
            change_obj[last_key] = '';  
                break;  
            case 'number':  
            change_obj[last_key] = 0;  
                break;  
            case 'boolean':  
            change_obj[last_key] = false;  
                break;  
    
    }
    
    
    }else if(data_type=='insert'){
        // let before_idx=obj_.before_idx;
        let change_obj=_this.data;
        // let last_path=null;
        // console.log("insert检查-1 obj_",obj_)
        // console.log("insert检查 前data",JSON.parse(JSON.stringify(_this.data.data)))
        if (path.indexOf(".") !== -1){
            let path_lst=path.split(".");
            for (let i=0;i<path_lst.length-1;i++){change_obj=change_obj[path_lst[i]]}
            last_path=path_lst[path_lst.length-1];
        }else{last_path=path}
        // let new_val=JSON.parse(JSON.stringify(change_obj[last_path]));
        
        // if (before_idx===null || (!(before_idx===undefined))){
        //     new_val.push(JSON.parse(JSON.stringify(obj_.copy_data)));
        // }else{
        //     new_val.splice(before_idx,0,JSON.parse(JSON.stringify(obj_.copy_data))); 
        // }
        console.log("insert检查 path",path)
        console.log("insert检查 change_obj,last_path,new_val",change_obj,last_path)
        _this.$set(change_obj,last_path,JSON.parse(JSON.stringify(data)))
        console.log("insert检查 后data",JSON.parse(JSON.stringify(_this.data)))
        //类型为删除
        }
    }
    let isPlainObject=function(variable) {  
        return variable !== null &&  
               typeof variable === 'object' &&  
               !Array.isArray(variable) &&  
               Object.getPrototypeOf(variable) === Object.prototype;  
    } 
    let isArray=function(variable) {  
        return Array.isArray(variable)
    } 
    _this.lhp_set1=function(obj_){
        let data_type=obj_.data_type;//要修改的数据类型  post||put delete clear
        let _this=obj_._this;//this vue对象
        let path=obj_.path;//path为data_obj要修改的数据的路径
        let data=obj_.data;//data为修改的数据
        // console.log("lhp_set1",obj_)
        //类型为新增或者修改
        if (data_type=='postput'){
        let change_obj=_this.data;
        let last_path=null;
        if (path.indexOf(".") !== -1){
            let path_lst=path.split(".");
            for (let i=0;i<path_lst.length-1;i++){change_obj=change_obj[path_lst[i]]}
            last_path=path_lst[path_lst.length-1];
        }else{last_path=path}
        // console.log("change_obj",change_obj)
        // console.log("last_path",last_path)
        if(isPlainObject(change_obj)){
            if(change_obj.hasOwnProperty(last_path)){
                lhp_deepcopy1(change_obj[last_path],JSON.parse(JSON.stringify(data)));

            }else{
                change_obj[last_path]=JSON.parse(JSON.stringify(data));
            }
        }else if(isArray(change_obj)){
            if(change_obj[last_path]!=undefined){
                lhp_deepcopy1(change_obj[last_path],JSON.parse(JSON.stringify(data)));
            }else{
                change_obj[last_path]=JSON.parse(JSON.stringify(data));
            }
        }
        // console.log("path",path)
        // console.log("_this.$set(change_obj,last_path,data)",change_obj,last_path,data)
        // lhp_deepcopy1(change_obj,JSON.parse(JSON.stringify(data)));
        //类型为删除
        }else if(data_type=="delete"){
            let change_obj=_this.data;
            let father_idx=null;
            let father_obj=null;
            if (path.indexOf(".") !== -1){
                let path_lst=path.split(".");
                if (path_lst.length<=1){console.log("delete异常 数量小于等于1");
return}
                for (let i=0;i<path_lst.length-1;i++){father_obj=change_obj;father_idx=path_lst[i];change_obj=change_obj[path_lst[i]];}
                let last_idx=path_lst[path_lst.length-1];
                // let new_data=JSON.parse(JSON.stringify(change_obj));
                if(typeof change_obj =="object") {  
                    if (Array.isArray(new_data)){
                        change_obj.splice(last_idx,1);
    
                    }else{
                        delete change_obj[last_idx];
                    }
            }}else{console.log("delete异常 数量小于2");
return}
    
            
    //类型为清空数据
    }else if(data_type=="clear"){
        let change_obj=_this.data;
        let last_key=null;
        if (path.indexOf(".") !== -1){
            let path_lst=path.split(".");
            for (let i=0;i<path_lst.length-1;i++){change_obj=change_obj[path_lst[i]]}
            last_key=path_lst[path_lst.length-1];
        }else{
            last_key=path;
        
        }
        let temp_val=change_obj[last_key]
    switch (typeof temp_val) {  
            case 'object':  
                // 注意：这里会匹配到null，因为null也是object类型  
                // 需要额外检查是否为null  
                if (temp_val === null) {  
                    change_obj[last_key] = null; // 或者你可以将null也设置为{}  
                } else if (Array.isArray(temp_val)) {  
                    change_obj[last_key] = [];  
                } else {  
                    change_obj[last_key] = {};  
                }  
                break;  
            case 'string':  
            change_obj[last_key] = '';  
                break;  
            case 'number':  
            change_obj[last_key] = 0;  
                break;  
            case 'boolean':  
            change_obj[last_key] = false;  
                break;  
    
    }
    
    
    }else if(data_type=='insert'){
        // let before_idx=obj_.before_idx;
        let change_obj=_this.data;
        // let last_path=null;
        // console.log("insert检查-1 obj_",obj_)
        // console.log("insert检查 前data",JSON.parse(JSON.stringify(_this.data.data)))
        if (path.indexOf(".") !== -1){
            let path_lst=path.split(".");
            for (let i=0;i<path_lst.length-1;i++){change_obj=change_obj[path_lst[i]]}
            last_path=path_lst[path_lst.length-1];
        }else{last_path=path}
        change_obj[last_path]=JSON.parse(JSON.stringify(data));
        //类型为删除
        }
    }
    //注册全局配置对象   register({"type":"try1","func":"要运行","param_path":xx.xx.xx,"recv_func":func})
    //     type:'try1',//首次执行报错跳过，后续再执行如果报错就删除当前对象
    //     type:'try2',//执行后如果报错就删除对象
    //     type:'try3',//报错不删除对象
    //     func:'',//要运行的函数名称
    //     check_param_path:'',//要检查的数据有变动的索引  如{a:{b:1}}变为{a:{b:2}} 这里值就为a.b
    //     recv_func:'' //向服务器更新数据的请求回调函数
    // 注册后 获得主动获取数据的函数
    // get_data(now_data) 主动获取注册路径的数据 now_data为当前数据
    _this.register=null
    // 注册更新
    // 当数据更新、初始化时 会判断目标路径的值的md5是否产生变化 产生变化则 将变化后的数据传入回调函数中
    _this.match_obj=function(obj){
        for(let i=0;i<_this.objs.length;i++){
            if(_this.objs[i]==obj){return i}
        }
    }
    _this.register=function(obj_data){
        // obj_data={
        //   _this:组件库_主侧栏.return_this(),//vue对象
        //   other_callback:{},//其他监听回调
        //   path:'template_config',//注册路径 /将此数据绑定到组件上
        //   type:"try3", // 报错不删除此注册[运行 func报错时不直接删除该注册对象]
        //   vname:"data",// 将接收的的完整数据保存到   vue对象.data[vname]
        //   func:function(){//将接收的的完整数据保存到   vue对象.data[vname]后 要执行的函数

        //   }
        // }   
        let func_=obj_data.func;
        let recv_data_name=obj_data.vname;
        let var_name=obj_data._this.data.var_name;
        obj_data.run_func1=function(obj_){
            // try{_this.lhp_set1(obj_);}catch (err){console.log("更新数据时运行run_func1函数出错1",err.stack)}
            try{func_(obj_);}catch (err){console.log("更新数据时运行run_func1函数出错2",err.stack);
}
        }
        obj_data.run_func2=function(obj_){
            // try{
                _this.lhp_vue_set(obj_);
            // }catch (err){
            //     console.log("更新数据时运行run_func2函数出错1",err.stack);
            // try{_this.lhp_vue_set(obj_);}catch (err){console.log("更新数据时运行run_func2函数出错1",err.stack);
// }
            try{func_(obj_);}catch (err){console.log("更新数据时运行run_func2函数出错2",err.stack);
}
        }
        obj_data.func=function(obj){
            _this.data.test_flag=true;
            _this.log_print("【",var_name,obj_data._this,"】","传参数据2:",obj);
            _this.log_print("【",var_name,obj_data._this,"】","调用回调函数")
            let path=obj.path;//更新数据的路径
            let data_type=obj.data_type;
            let data=obj.data;
            if(path==''){path=recv_data_name}else{path=recv_data_name+'.'+path}
            log_print("【",var_name,obj_data._this,"】","更新数据和路径:",path,data);
            let ooobj=JSON.parse(JSON.stringify(obj));
            ooobj._this=obj_data._this;
            ooobj.path=path;
            // ooobj._this=obj_data._this;
            // let ooobj={data_type:data_type,_this:,path:,data:data,before_idx:obj.before_idx,type:obj.type};
            if(obj_data.add_time_func){
                if(obj_data.lhp_set1){
                    obj_data.add_time_func({
                        func:obj_data.run_func1,
                        params:ooobj
                    })
                }else{
                    obj_data.add_time_func({
                        func:obj_data.run_func2,
                        params:ooobj
                    })
                }
            }else{
                if (obj_data.lhp_set1){
                    obj_data.run_func1(ooobj);
                }else{
                    obj_data.run_func2(ooobj);
                }
            }
        }
        obj_data.md5={};

        _this.objs.push(obj_data);
        _this.log_print("【",var_name,obj_data._this,"】","注册中:",)
        
        //主动获取注册路径的数据
        let get_data=function(){
            _this.log_print("【",var_name,obj_data._this,"】","初始化数据:2",);
            if(Object.keys(_this.data).length==0){return}//如果data没有数据 则之间跳过执行内容
            // let now_md5=md5(JSON.stringify(now_data));//获取当前的md5
            let path2=obj_data.path;
            
            _this.log_print("【",var_name,obj_data._this,"】","初始化数据:3",path2,);
            let temp_val1=_this.data,temp_val2=[];
            if(path2!=''){temp_val2=path2.split(".");}
            _this.log_print("【",var_name,obj_data._this,"】","初始化数据:4",path2,);
            for(let j=0;j<temp_val2.length;j++){temp_val1=temp_val1[temp_val2[j]]}
            _this.log_print("【",var_name,obj_data._this,"】","初始化数据:5",path2,);
            // let new_md5=md5(JSON.stringify(temp_val1));//获取最新的md5
            //md5不同 则直接更新数据
            // if (!(new_md5===now_md5)){
                try{obj_data.func({path:'',data:temp_val1,data_type:"postput",type:"change_data"})}
                catch(err){
                    _this.log_print(err)
                    let del_idx=null;
                    if (obj_data.type=="try1" || obj_data.type=="try2"){del_idx=_this.match_obj(obj_data);}
                    if(obj_data["error_count"]===undefined){obj_data["error_count"]=1;}
                    else{obj_data["error_count"]++;}
                    if (obj_data.type=='try1'&&obj_data["error_count"]>1){
                        _this.objs.slice(del_idx,1);}
                    else if (obj_data.type=='try2'){_this.objs.slice(del_idx,1);}
                }
                if(obj_data._this.data.test_flag==true){_this.log_print("初始化数据:6")}
            // }
        }
        _this.log_print("【",var_name,obj_data._this,"】","注册-开始 获取初始化数据",);
        get_data();
        _this.log_print("【",var_name,obj_data._this,"】","注册-结束 获取初始化数据",);
        return get_data
    }  
//向服务器更新数据 obj={"path:"xx.xx.xx","data":"data"} path为要更新的完整路径
    _this.update=function(update_obj){
        // update_obj.params=_this.return_params();//添加附带参数如账号信息
        update_obj.params={};//添加附带参数如账号信息
        update_obj.type="change_data";//表示更新数据
        update_obj.template_name=_this.template_name
        
        for(let i=0;i<_this.add_params_func_lst.length;i++){
            lhp_deepcopy1(update_obj.params,lhp_run_func(_this.add_params_func_lst[i]))
        }
        _this.ws.send(JSON.stringify(update_obj));//向服务器发送更新数据请求
    }
    _this.get_all=function(){
        _this.log_print("开始获取服务器所有数据")
        let params={};//添加附带参数如账号信息
        for(let i=0;i<_this.add_params_func_lst.length;i++){
            lhp_deepcopy1(params,lhp_run_func(_this.add_params_func_lst[i]))
        }
        _this.ws.send(JSON.stringify({template_name:_this.template_name,params:params,"type":"regist",path:params.path}));
    }
    }
    

function up_ws_class2(add_params_func_lst) {  
let _this=this;
//创建对象
_this.update_obj=new up_ws_class1();
_this.update_obj.add_params_func_lst=add_params_func_lst;
_this.connect=async function(){
    console.log("开始连接服务器")
    await _this.update_obj.connect_socket();//连接服务器的websocket 连接成功执行回调函数
    _this.更新=function(obj){_this.update_obj.update(obj)}
    _this.注册=function(obj){console.log("开始注册：",_this.update_obj,_this.update_obj.register);_this.update_obj.register(obj);
}
    _this.初始化=function(){_this.update_obj.get_all()}
    console.log("连接服务器完成");
    console.log(`更新:`,_this.更新)
    console.log(`注册:`,_this.注册)
    console.log(`初始化:`,_this.初始化)
}
//开始连接服务器

//等待服务器连接成功
// while(1){
//     if(_this.update_obj.connect_flag){
//         console.log("websocket连接成功!");
//         _this.更新=function(obj){_this.update_obj.update(obj)}
//         _this.注册=function(obj){console.log("开始注册：",_this.update_obj,_this.update_obj.register);_this.update_obj.register(obj);
//}
//         _this.初始化=function(){_this.update_obj.get_all()}
//         break}
// }
}

//通过路由获取当前项目  所在的 用户id  项目目录  项目id
function getQueryParams() {  
    const queryParams = {};  
    const urlParams = new URLSearchParams(window.location.search);  
    for (const [key, value] of urlParams.entries()) {  
        queryParams[key] = value;  
    }  
    queryParams.regist_type="project"//配置类型 为 项目配置
    return queryParams;  
}  
async function time_sleep(sleep_time=2000) {
    return new Promise((resolve) => {
      setTimeout(() => {
        resolve('异步操作完成');
      }, sleep_time);
    });
  }
// user_id=str(params_.get("user_id"))
// project_dir=str(params_.get("project_dir"))
// project_id=str(params_.get("project_id"))
// 全局配置对象=new up_ws_class2(['getQueryParams']);

// 使用示例  
// (async () => {  
    
//     //初始化全局配置对象
//     window.全局配置对象 = new up_ws_class2(['getQueryParams']); 
//     //打开日志提示 
//     全局配置对象.log_flag=true;
//     //等待 建立websocket连接完成
//     await 全局配置对象.connect();
//     //等待连接完成
//     while(1){await time_sleep(0.1);console.log("连接中");
//if(全局配置对象.update_obj.connect_flag==true){break;}}
//     //获取所有配置
//     全局配置对象.初始化();
//     //等待获取所有配置完成
//     while(1){await time_sleep(0.1);console.log("获取配置中");if(全局配置对象.update_obj.get_all_flag==true){break;}}
//     //打印测试
//     console.log("全局配置对象.update_obj.data",全局配置对象.update_obj.data);

//   })();
